﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace TinyEngine.Core.Common
{
    public class Interpolator
    {
        public float From { get; set; }
        public float To { get; set; }
        public Action<Interpolator> Changed { get; set; }
        public Action<Interpolator> Completed { get; set; }
        public float Time { get; set; }
        private float internalTimer;

        internal Interpolator(float from, float to, float time, Action<Interpolator> Changed, Action<Interpolator> Complete)
        {
            this.From = from;
            this.To = to;
            this.Changed = Changed;
            this.Completed = Complete;
            this.Time = time;    
        }

        public static Interpolator Create(float from, float to, float time, Action<Interpolator> Changed, Action<Interpolator> Complete)
        {
            var i = new Interpolator(from, to, time, Changed, Complete);
            interpolators.Add(i);
            return i;
        }
        
        static List<Interpolator> interpolators = new List<Interpolator>();
        
        public static void Update(float elapsed)
        {
            List<Interpolator> toRemove = new List<Interpolator>();
            foreach (var item in interpolators)
            {
                item.UpdateInternal(elapsed);
                if (item.HasCompleted)
                {
                    toRemove.Add(item);
                }
            }
            foreach (var item in toRemove)
            {
                if (item.Completed != null)
                    item.Completed(item);

                interpolators.Remove(item);
            }
        }
        
        void UpdateInternal(float elapsed)
        {
            internalTimer += elapsed;
            var distance = internalTimer / Time;
            this.Value = MathHelper.Lerp(this.From, To, distance);
            if (Changed != null)
                Changed(this);

            if(To > From && Value >= To)
            {
                Value = To;
            }
            else if (To < From && Value <= To)
            {
                Value = To;
            }
        }
        
        public float Value { get; set; }
        
        public bool HasCompleted
        {
            get
            {
                return Value == To;
            }
        }
    }
}
